package com.bird.system.service.impl;

import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.net.URLEncoder;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.bird.common.utils.StringUtil;
import com.bird.common.utils.covert.ApiIdCovert;
import com.bird.system.domain.entity.TsGroupApiEntity;
import com.bird.system.domain.params.TsGroupApiQueryParam;
import com.bird.system.domain.params.TsGroupApiUpdateParam;
import com.bird.system.domain.vo.TsGroupApiListPcVO;
import com.bird.system.mapper.TsGroupApiMapper;
import com.bird.system.service.ITsGroupApiService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

/**
 * 组接口Service业务层处理
 *
 * @author bird
 * @date 2020-09-23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TsGroupApiServiceImpl extends IBaseServiceImpl<TsGroupApiEntity, TsGroupApiMapper> implements ITsGroupApiService {

	/**
	 * 查询组接口列表
	 *
	 * @param queryParam 组接口 查询参数
	 * @return 组接口
	 */
	@Override
	public List<TsGroupApiListPcVO> selectListPC(TsGroupApiQueryParam queryParam) {
		List<TsGroupApiListPcVO> tsGroupApis = mapper.selectListPC(queryParam);
		return tsGroupApis;
	}

	/**
	 * 新增组接口
	 *
	 * @param updateParam 组接口 新增参数
	 * @return 结果
	 */
	@Override
	public Long insertPC(TsGroupApiUpdateParam updateParam, Long userId) {
		// 数据处理转换
		TsGroupApiEntity entity = updateParam.covert();
		keyValueCovertSourceData(entity);
		entity.setCreSb(userId);
		this.insert(entity);
		return entity.getId();
	}

	/**
	 * 修改组接口
	 *
	 * @param updateParam 组接口 修改参数
	 * @return 结果
	 */
	@Override
	public int updateByIdPC(TsGroupApiUpdateParam updateParam) {
		TsGroupApiEntity entity = updateParam.covert();
		keyValueCovertSourceData(entity);
		int result = this.updateById(entity);
		// 删除本地缓存
		ApiIdCovert.existUser.remove(updateParam.getId());
		return result;
	}

	/**
	 * key:value 转数据库存储
	 *
	 * @param tsGroupApiEntity
	 */
	@Override
	public void keyValueCovertSourceData(TsGroupApiEntity tsGroupApiEntity) {
		// 数据处理转换
		tsGroupApiEntity.setBodyParam(keyValueDataCovertJson(tsGroupApiEntity.getBodyParam()));
		tsGroupApiEntity.setHeaderParam(keyValueDataCovertJson(tsGroupApiEntity.getHeaderParam()));
		tsGroupApiEntity.setUrlParam(keyValueDataCovertUrlParam(tsGroupApiEntity.getUrlParam()));
	}

	/**
	 * 数据库转 key:value
	 *
	 * @param tsGroupApiEntity
	 */
	@Override
	public void sourceDataCovertKeyValue(TsGroupApiEntity tsGroupApiEntity) {
		// 数据处理转换
		tsGroupApiEntity.setBodyParam(jsonDataCovertKeyValue(tsGroupApiEntity.getBodyParam()));
		tsGroupApiEntity.setHeaderParam(jsonDataCovertKeyValue(tsGroupApiEntity.getHeaderParam()));
		tsGroupApiEntity.setUrlParam(urlParamCovertKeyValueData(tsGroupApiEntity.getUrlParam()));
	}

	/**
	 * key:value 数据转json
	 *
	 * @param data
	 * @return
	 */
	@Override
	public String keyValueDataCovertJson(String data) {
		if (StringUtil.isBlank(data)) {
			return data;
		}
		JSONObject jsonObject = new JSONObject(true);
		String[] groupData = data.replaceAll("\n+", "\n").split("\n");
		for (String groupDatum : groupData) {
			int first = groupDatum.indexOf(":");
			if (first > -1) {
				String key = groupDatum.substring(0, first);
				String keyValue = groupDatum.substring(first + 1, groupDatum.length());
				if (NumberUtil.isNumber(keyValue)) {
					jsonObject.put(key, NumberUtil.parseNumber(keyValue));
				} else {
					jsonObject.put(key, keyValue);
				}
			}
		}
		return jsonObject.toJSONString();
	}

	/**
	 * json数据转  key:value
	 *
	 * @param data
	 * @return
	 */
	@Override
	public String jsonDataCovertKeyValue(String data) {
		if (StringUtil.isBlank(data)) {
			return data;
		}
		JSONObject jsonObject = JSONObject.parseObject(data, Feature.OrderedField);
		StringBuilder stringBuilder = new StringBuilder();
		jsonObject.forEach((key, value) -> {
			value = value == null ? "" : value;
			stringBuilder.append(key).append(":").append(value).append("\n");
		});
		return stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
	}

	/**
	 * key:value 数据转 UrlParam
	 *
	 * @param data
	 * @return
	 */
	@Override
	public String keyValueDataCovertUrlParam(String data) {
		if (StringUtil.isBlank(data)) {
			return data;
		}
		JSONObject json = new JSONObject(true);
		String[] groupData = data.replaceAll("\n+", "\n").split("\n");
		for (String groupDatum : groupData) {
			int first = groupDatum.indexOf(":");
			if (first > -1) {
				String key = groupDatum.substring(0, first);
				String keyValue = groupDatum.substring(first + 1, groupDatum.length());
				if (NumberUtil.isNumber(keyValue)) {
					json.put(key, NumberUtil.parseNumber(keyValue));
				} else {
					json.put(key, keyValue);
				}
			}
		}
		StringBuilder param = new StringBuilder();
		for (Map.Entry<String, Object> entry : json.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			param.append(key + "=");
			if (value != null) {
				param.append(value);
			}
			param.append("&");
		}
		if (param.length() > 0) {
			param.deleteCharAt(param.lastIndexOf("&"));
		}

		return URLEncoder.createDefault().encode(param.toString(), Charset.defaultCharset());

	}

	/**
	 * key:value 数据转 UrlParam
	 *
	 * @param data
	 * @return
	 */
	@Override
	public String urlParamCovertKeyValueData(String data) {
		if (StringUtil.isBlank(data)) {
			return data;
		}

		data = URLDecoder.decode(data, Charset.defaultCharset());

		StringBuilder params = new StringBuilder();
		String[] groupData = data.split("&");
		for (String groupDatum : groupData) {
			String[] keyValue = groupDatum.split("=");
			params.append(keyValue[0]).append(":");
			if (keyValue.length > 1) {
				params.append(keyValue[1]);
			} else {
				params.append("");
			}
			params.append("\n");
		}
		return params.toString();
	}

	@Override
	public String selectNameById(Long id) {
		return this.selectField(TsGroupApiEntity::getTheName, SelectWhere().andEqualTo(TsGroupApiEntity::getId, id).end());
	}

	@Override
	public TsGroupApiEntity selectByIdPc(Long id) {
		TsGroupApiEntity tsGroupApiEntity = this.selectById(id);
		sourceDataCovertKeyValue(tsGroupApiEntity);
		return tsGroupApiEntity;
	}
}
